package com.electromagnetic.industry.software.manage.service.serviceimpl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.PublishEnum;
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper;
import com.electromagnetic.industry.software.manage.mapper.EdTagLibraryMapper;
import com.electromagnetic.industry.software.manage.mapper.FileTagRelationMapper;
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
import com.electromagnetic.industry.software.manage.pojo.models.EdTagLibrary;
import com.electromagnetic.industry.software.manage.pojo.models.FileTagRelation;
import com.electromagnetic.industry.software.manage.pojo.resp.FileTagInfo;
import com.electromagnetic.industry.software.manage.service.FileTagRelationService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class FileTagRelationServiceImpl extends ServiceImpl<FileTagRelationMapper, FileTagRelation> implements FileTagRelationService {
    @Autowired
    private EdTagLibraryMapper edTagLibraryMapper;
    @Resource
    private EdFileInfoMapper edFileInfoMapper;
    @Autowired
    private CommonService commonService;

    private boolean addTagToFile(String fileId, String tagId, String createdBy) {
        // 检查标签是否存在并且已发布
        EdTagLibrary tag = edTagLibraryMapper.selectOne(new LambdaQueryWrapper<EdTagLibrary>()
                .eq(EdTagLibrary::getTagId, tagId)
                .eq(EdTagLibrary::getIsPublished, PublishEnum.PUBLISHED.getCode())
                .eq(EdTagLibrary::getEffectFlag, EffectFlagEnum.EFFECT.code));
        Assert.notNull(tag, "标签不存在或未发布");

        // 查询或创建关联关系
        FileTagRelation relation = this.getOne(new LambdaQueryWrapper<FileTagRelation>()
                .eq(FileTagRelation::getFileId, fileId)
                .eq(FileTagRelation::getTagId, tagId));

        boolean result;
        if (relation == null) {
            relation = new FileTagRelation();
            relation.newInit();
            relation.setFileId(fileId);
            relation.setTagId(tagId);
            result = this.save(relation);
        } else {
            // 恢复已删除的关联
            relation.setEffectFlag(EffectFlagEnum.EFFECT.code);
            relation.setUpdatedBy(createdBy);
            result = this.updateById(relation);
        }
        return result;
    }

    /**
     * 批量添加标签到文件
     *
     * @param fileId
     * @param tagIds
     * @param createdBy
     * @return
     */
    @Override
    @Transactional
    public boolean addTagsToFile(String fileId, List<String> tagIds, String createdBy) {

        Assert.notEmpty(tagIds, "标签列表不能为空");
        boolean isSuccess = true;
        for (String tagId : tagIds) {
            isSuccess &= addTagToFile(fileId, tagId, createdBy);
        }
        edFileInfoMapper.update(new EdFileInfo(), Wrappers.lambdaUpdate(EdFileInfo.class).eq(EdFileInfo::getId, fileId).set(EdFileInfo::getPermanentDeleted, false));
        if (isSuccess) {

            String tags = edTagLibraryMapper.selectList(new LambdaQueryWrapper<EdTagLibrary>()
                    .in(EdTagLibrary::getTagId, tagIds)
                    .select(EdTagLibrary::getTagName)
                    .eq(EdTagLibrary::getEffectFlag, EffectFlagEnum.EFFECT.code)
                    .eq(EdTagLibrary::getIsPublished, PublishEnum.PUBLISHED.getCode())).stream().map(EdTagLibrary::getTagName).collect(Collectors.joining(","));

            EdFileInfo fileInfo = edFileInfoMapper.selectById(fileId);
            String dbPath = commonService.getDbPath(fileInfo.getFilePath());
            UserThreadLocal.setSuccessInfo(Optional.of(fileInfo).map(EdFileInfo::getParentId).orElse(""), fileId, "添加了标签 {} 到文件 {}", tags, dbPath);
        }
        return isSuccess;
    }

    /**
     * 获取文件标签
     *
     * @param fileId
     * @return
     */
    @Override
    public List<FileTagInfo> getFileTags(String fileId) {
        LambdaQueryWrapper<FileTagRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileTagRelation::getFileId, fileId)
                .eq(FileTagRelation::getEffectFlag, EffectFlagEnum.EFFECT.code);
        List<FileTagRelation> relations = this.list(queryWrapper);
        List<FileTagInfo> result = new ArrayList<>();
        for (FileTagRelation relation : relations) {
            EdTagLibrary tagInfo = edTagLibraryMapper.selectById(relation.getTagId());
            if (Objects.isNull(tagInfo)) {
                continue;
            }
            FileTagInfo vo = new FileTagInfo();
            BeanUtils.copyProperties(tagInfo, vo);
            result.add(vo);
        }
        return result;
    }

    /**
     * 根据 tagIds 获取文件 ID 列表
     *
     * @param tagIds
     * @return
     */
    @Override
    public List<String> getFileIdsByTagIds(List<String> tagIds) {
        LambdaQueryWrapper<FileTagRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(FileTagRelation::getTagId, tagIds)
                .eq(FileTagRelation::getEffectFlag, EffectFlagEnum.EFFECT.code);
        List<FileTagRelation> relations = this.list(queryWrapper);
        return relations.stream()
                .map(FileTagRelation::getFileId)
                .distinct()
                .toList();
    }

    /**
     * 逻辑删除文件标签关系
     *
     * @param fileId
     * @param tagId
     * @return
     */
    @Override
    public boolean logicRemove(String fileId, String tagId) {
        if (fileId == null && tagId == null) {
            throw new IllegalArgumentException("必须提供至少一个参数");
        }
        return this.update(
                new LambdaUpdateWrapper<FileTagRelation>()
                        .set(FileTagRelation::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
                        .eq(fileId != null, FileTagRelation::getFileId, fileId)
                        .eq(tagId != null, FileTagRelation::getTagId, tagId)
                        .eq(FileTagRelation::getEffectFlag, EffectFlagEnum.EFFECT.code)
        );
    }
}